#include "DXUT.h"
#include "Moveable.h"

 

IMoveable::IMoveable( const D3DXVECTOR3 & Pos /*=D3DXVECTOR3(0.0f,0.0f,0.0f)*/,const D3DXVECTOR3 & Volicity/*=D3DXVECTOR3(0.0f,0.0f,0.0f)*/,const D3DXVECTOR3 & scale/*=D3DXVECTOR3(1.0f,1.0f,1.0f)*/,D3DXVECTOR3 & Rot/*=D3DXVECTOR3(0.0f,0.0f,0.0f) */ )
{

	SetTranslation(Pos);
	SetRotation( Rot );
	Scale(scale);

	SetVelocity( Volicity );
	SetSpin( 0.0f, 0.0f, 0.0f );


	m_forward = D3DXVECTOR3( 0.0f, 0.0f, 1.0f );
	m_right = D3DXVECTOR3( 1.0f, 0.0f, 0.0f );


	m_friction = 0.0f;


	m_collisionStamp = -1;

	m_visible = true;
	m_enabled = true;

	m_ignoreCollisions = false;


	m_touchingGround = false;





	D3DXMatrixMultiply( &m_matWorld, &m_matRotation, &m_matTranslate );
}


IMoveable::~IMoveable(void)
{
}

 
 




//-----------------------------------------------------------------------------
// Called when something collides with the object.
//-----------------------------------------------------------------------------
void IMoveable::CollisionOccurred( IMoveable *object, unsigned long collisionStamp )
{
	// Set the collision stamp.
	m_collisionStamp = collisionStamp;
}

//-----------------------------------------------------------------------------
// Applies the given force to the object in the forwards/backwards direction.
//-----------------------------------------------------------------------------
void IMoveable::Drive( float force, bool lockYAxis )
{
	D3DXVECTOR3 realForce = m_forward * force;

	m_velocity.x += realForce.x;
	m_velocity.z += realForce.z;

	if( lockYAxis == false )
		m_velocity.y += realForce.y;
}

//-----------------------------------------------------------------------------
// Applies the given force to the object in the right/left direction.
//-----------------------------------------------------------------------------
void IMoveable::Strafe( float force, bool lockYAxis )
{
	D3DXVECTOR3 realForce = m_right * force;

	m_velocity.x += realForce.x;
	m_velocity.z += realForce.z;

	if( lockYAxis == false )
		m_velocity.y += realForce.y;
}

//-----------------------------------------------------------------------------
// Stops the object moving.
//-----------------------------------------------------------------------------
void IMoveable::Stop()
{
	m_velocity = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
	m_spin = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
}

//-----------------------------------------------------------------------------
// Sets the object's translation.
//-----------------------------------------------------------------------------
void IMoveable::SetTranslation( float x, float y, float z )
{
	m_vPos.x = x;
	m_vPos.y = y;
	m_vPos.z = z;

D3DXMatrixTranslation( &m_matTranslate, m_vPos.x, m_vPos.y, m_vPos.z );
}

//-----------------------------------------------------------------------------
// Sets the object's translation.
//-----------------------------------------------------------------------------
void IMoveable::SetTranslation( D3DXVECTOR3 translation )
{
	m_vPos = translation;

	D3DXMatrixTranslation( &m_matTranslate, m_vPos.x, m_vPos.y, m_vPos.z );
}

//-----------------------------------------------------------------------------
// Adds the given translation to the object's current translation.
//-----------------------------------------------------------------------------
void IMoveable::AddTranslation( float x, float y, float z )
{
	m_vPos.x += x;
	m_vPos.y += y;
	m_vPos.z += z;

D3DXMatrixTranslation( &m_matTranslate, m_vPos.x, m_vPos.y, m_vPos.z );
}

//-----------------------------------------------------------------------------
// Adds the given translation to the object's current translation.
//-----------------------------------------------------------------------------
void IMoveable::AddTranslation( D3DXVECTOR3 translation )
{
	m_vPos += translation;

	D3DXMatrixTranslation( &m_matTranslate, m_vPos.x, m_vPos.y, m_vPos.z );
}

//-----------------------------------------------------------------------------
// Returns the object's translation.
//-----------------------------------------------------------------------------
D3DXVECTOR3 IMoveable::GetTranslation()
{
	return m_matTranslate;
}

//-----------------------------------------------------------------------------
// Sets the object's rotation.
//-----------------------------------------------------------------------------
void IMoveable::SetRotation( float x, float y, float z )
{
	m_vRot.x = x;
	m_vRot.y = y;
	m_vRot.z = z;
	D3DXMATRIX rotationX, rotationY;
	D3DXMatrixRotationX( &rotationX, m_vRot.x );
	D3DXMatrixRotationY( &rotationY, m_vRot.y );
	D3DXMatrixRotationZ( &m_matRotation, m_vRot.z );
	D3DXMatrixMultiply( &m_matRotation,&m_matRotation, &rotationX );
	D3DXMatrixMultiply( &m_matRotation, &m_matRotation, &rotationY );
}

//-----------------------------------------------------------------------------
// Sets the object's rotation.
//-----------------------------------------------------------------------------
void IMoveable::SetRotation( D3DXVECTOR3 rotation )
{
	m_vRot = rotation;

	D3DXMATRIX rotationX, rotationY;
	D3DXMatrixRotationX( &rotationX, m_vRot.x );
	D3DXMatrixRotationY( &rotationY, m_vRot.y );
	D3DXMatrixRotationZ( &m_matRotation, m_vRot.z );
	D3DXMatrixMultiply( &m_matRotation,&m_matRotation, &rotationX );
	D3DXMatrixMultiply( &m_matRotation, &m_matRotation, &rotationY );
}

//-----------------------------------------------------------------------------
// Adds the given rotation to the object's current rotation.
//-----------------------------------------------------------------------------
void IMoveable::AddRotation( float x, float y, float z )
{
	m_vRot.x += x;
	m_vRot.y += y;
	m_vRot.z += z;

	D3DXMATRIX rotationX, rotationY;
	D3DXMatrixRotationX( &rotationX, m_vRot.x );
	D3DXMatrixRotationY( &rotationY, m_vRot.y );
	D3DXMatrixRotationZ( &m_matRotation, m_vRot.z );
	D3DXMatrixMultiply( &m_matRotation,&m_matRotation, &rotationX );
	D3DXMatrixMultiply( &m_matRotation, &m_matRotation, &rotationY );
}

 
void IMoveable::AddRotation( D3DXVECTOR3 rotation )
{
	m_vRot += rotation;

	D3DXMATRIX rotationX, rotationY;

	D3DXMatrixRotationX( &rotationX, m_vRot.x );
	D3DXMatrixRotationY( &rotationY, m_vRot.y );
	D3DXMatrixRotationZ( &m_matRotation, m_vRot.z );
	D3DXMatrixMultiply( &m_matRotation,&m_matRotation, &rotationX );
	D3DXMatrixMultiply( &m_matRotation, &m_matRotation, &rotationY );
}

 
D3DXVECTOR3 IMoveable::GetRotation()
{
	return m_vRot;
}
 
void IMoveable::SetVelocity( float x, float y, float z )
{
	m_velocity.x = x;
	m_velocity.y = y;
	m_velocity.z = z;
}

 
void IMoveable::SetVelocity( D3DXVECTOR3 velocity )
{
	m_velocity = velocity;
}
 
void IMoveable::AddVelocity( float x, float y, float z )
{
	m_velocity.x += x;
	m_velocity.y += y;
	m_velocity.z += z;
}

 
void IMoveable::AddVelocity( D3DXVECTOR3 velocity )
{
	m_velocity += velocity;
}

 
D3DXVECTOR3 IMoveable::GetVelocity()
{
	return m_velocity;
}

 
void IMoveable::SetSpin( float x, float y, float z )
{
	m_spin.x = x;
	m_spin.y = y;
	m_spin.z = z;
}
 
void IMoveable::SetSpin( D3DXVECTOR3 spin )
{
	m_spin = spin;
}

 
void IMoveable::AddSpin( float x, float y, float z )
{
	m_spin.x += x;
	m_spin.y += y;
	m_spin.z += z;
}
 
void IMoveable::AddSpin( D3DXVECTOR3 spin )
{
	m_spin+= spin;
}

 
D3DXVECTOR3 IMoveable::GetSpin()
{
	return m_spin;
}

 
D3DXVECTOR3 IMoveable::GetForwardVector()
{
	return m_forward;
}

 
D3DXVECTOR3 IMoveable::GetRightVector()
{
	return m_right;
}

 
D3DXMATRIX *IMoveable::GetTranslationMatrix()
{
	return &m_matTranslate;
}

 
D3DXMATRIX *IMoveable::GetRotationMatrix()
{
	return &this->m_matRotation;
}
 
D3DXMATRIX *IMoveable::GetWorldMatrix()
{
	return & this->m_matWorld;
}

 
 

 
void IMoveable::SetFriction( float friction )
{
	m_friction = friction;
}

 
unsigned long IMoveable::GetCollisionStamp()
{
	return m_collisionStamp;
}

 
void IMoveable::SetVisible( bool visible )
{
	m_visible = visible;
}

 
bool IMoveable::GetVisible()
{
	return m_visible;
}
 
void IMoveable::SetEnabled( bool enabled )
{
	m_enabled = enabled;
}

 
bool IMoveable::GetEnabled()
{
	return m_enabled;
}

 

 
void IMoveable::SetIgnoreCollisions( bool ignoreCollisions )
{
	m_ignoreCollisions = ignoreCollisions;
}
 
bool IMoveable::GetIgnoreCollisions()
{
	return m_ignoreCollisions;
}

 
void IMoveable::SetTouchingGroundFlag( bool touchingGround )
{
	m_touchingGround = touchingGround;
}

 
bool IMoveable::IsTouchingGround()
{
	return m_touchingGround;
 
}

void IMoveable::Scale( float x,float y ,float z )
{
	m_vScale=D3DXVECTOR3(x,y,z);
	D3DXMatrixScaling( &m_matScale,m_vScale.x,m_vScale.y,m_vScale.z);
}

void IMoveable::Scale( const D3DXVECTOR3 & scale )
{
	m_vScale=scale;
	D3DXMatrixScaling( &m_matScale,m_vScale.x,m_vScale.y,m_vScale.z);
}

void IMoveable::SetPos( const D3DXVECTOR3 & vpos )
{
	this->m_vPos=vpos;
	D3DXMatrixTranslation(&m_matTranslate,vpos.x,vpos.y,vpos.z);
}

void IMoveable::SetPos( float x,float y ,float z )
{
	this->m_vPos=D3DXVECTOR3(x,y,z);
	D3DXMatrixTranslation(&m_matTranslate,x,y,z);

}

void IMoveable::OnUpdate( double fTime, float fElapsedTime )
{
	SetPos(   m_vPos+m_velocity *fElapsedTime);

	D3DXMatrixMultiply( &m_matWorld, &m_matRotation, & m_matScale  );
    D3DXMatrixMultiply( &m_matWorld, &m_matWorld, &m_matTranslate );
}




